﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Diagnostics;
using System.IO;

namespace CFScript.Tasks
{
    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class Write : Task
    {
        public Write()
        {
            this.name = "<write>";
            this.parameterNames = new string[] { "path", "append"};
            this.parameterExpandable = new bool[] { true, false };
            this.parameterRequired = new bool[] { true, false };
            this.parameters = new Dictionary<string, Parameter>();
            this.hasInnerText = true;

            Debug.Assert(this.parameterNames.Length == this.parameterRequired.Length &&
                         this.parameterRequired.Length == this.parameterExpandable.Length);
        }

        public override InstructionResult Execute(CFScript context)
        {
            InstructionResult result = new InstructionResult();
            result.ExecutedInstruction = this;

            string path = this.parameters["path"].GetValue(context);
            bool appendText = this.parameters.ContainsKey("append") && this.parameters["append"].GetValueAsBoolean();
            StreamWriter file = null;

            try
            {
                if (!string.IsNullOrEmpty(this.innerText))
                {
                    string fileName = Path.GetFileName(path).Trim();

                    // FileInfo.Attributes is -1 if file doesn't exist

                    if (string.IsNullOrEmpty(fileName))
                    {
                        // Must be a file name, not a directory
                        result.Code = ResultCode.ERROR;
                        switch (context.Options.VerboseLevel)
                        {
                            case VerboseMode.MINIMUM:
                            case VerboseMode.ALL:
                                result.Message = "A file name was expected but a directory path found instead";
                                break;
                        }
                    }
                    else
                    {
                        FileInfo fi = new FileInfo(path);

                        if (!fi.Exists)
                        {
                            File.CreateText(path).Close();
                        }

                        file = new StreamWriter(path, appendText);
                        file.Write(context.ExpandValue(this.innerText.Trim()));
                        file.Flush();
                        file.Close();
                        result.Code = ResultCode.OK;
                    }
                }
                // else, it isn't necessary to create the file
            }
            catch (Exception ex)
            {
                result.Code = ResultCode.ERROR;
                result.Message = ex.Message;
            }
            finally
            {
                if (file != null)
                {
                    try
                    {
                        file.Close();
                    }
                    catch
                    { }
                }
            }

            result.BreakExecution = result.Code == ResultCode.ERROR && this.options.OnError == OnErrorAction.BREAK;

            return result;
        }
    }
}
